package com.tianzmp.ttq.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.tianzmp.ttq.admin.controller.reqDto.UserInfoPageList;
import com.tianzmp.ttq.admin.controller.reqDto.UserInfoUpdateDTO;
import com.tianzmp.ttq.admin.controller.reqDto.UserMenusDTO;
import com.tianzmp.ttq.admin.controller.resDto.MenuTree;
import com.tianzmp.ttq.admin.controller.resDto.UserInfoPageListResponse;
import com.tianzmp.ttq.admin.controller.resDto.UserInfoGetById;
import com.tianzmp.ttq.admin.entity.*;
import com.tianzmp.ttq.admin.exception.AdminBusinessException;
import com.tianzmp.ttq.admin.exception.ErrorEnum;
import com.tianzmp.ttq.admin.mapper.UserInfoAttachMapper;
import com.tianzmp.ttq.admin.mapper.UserInfoMapper;
import com.tianzmp.ttq.admin.service.IRoleService;
import com.tianzmp.ttq.admin.service.IUserInfoService;
import com.tianzmp.ttq.admin.service.IUserRoleService;
import com.tianzmp.ttq.admin.util.AssertUtils;
import com.tianzmp.ttq.admin.util.MapperUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户基本数据表 服务实现类
 * </p>
 *
 * @author ttq
 * @since 2022-07-26
 */
@Service
public class UserInfoServiceImpl implements IUserInfoService {

    @Autowired
    private UserInfoMapper dao;

    @Autowired
    private UserInfoAttachMapper userInfoAttachDao;

    @Autowired
    private IUserRoleService userRoleService;

    @Autowired
    private IRoleService roleService;

    @Override
    public List<UserInfo> list() {


        return dao.selectList(null);
    }

    @Override
    public PageInfo<List<UserInfoPageListResponse>> pageList(UserInfoPageList dto) {
        IPage<UserInfoPageListResponse> page =  new Page<UserInfoPageListResponse>(dto.getCurrent(),dto.getSize());
        MPJLambdaWrapper<UserInfo> queryWrapper = new MPJLambdaWrapper<UserInfo>()
                .selectAll(UserInfo.class)
                .select(UserInfoAttach::getPhone, UserInfoAttach::getEmail, UserInfoAttach::getImageId, UserInfoAttach::getMobile,UserInfoAttach::getQq)
                .selectAs(UpsFile::getFileUrl,UserInfoPageListResponse::getImageUrl)
                .selectCollection(UserRole.class,UserInfoPageListResponse::getRoles,map->map.result(UserRole::getRoleId))
                .leftJoin(UserInfoAttach.class, UserInfoAttach::getUserId, UserInfo::getId)
                .leftJoin(UpsFile.class,UpsFile::getId,UserInfoAttach::getImageId)
                .leftJoin(UserRole.class,UserRole::getUserId,UserInfo::getId)
                .eq(StringUtils.isNotBlank(dto.getUsername()), UserInfo::getUserName, dto.getUsername())
                .eq(StringUtils.isNotBlank(dto.getAccount()), UserInfo::getAccount, dto.getAccount())
                .orderByDesc(UserInfo::getId);
        IPage<UserInfoPageListResponse> result = dao.selectJoinPage(page,UserInfoPageListResponse.class,  queryWrapper);
        return new PageInfo(dto.getCurrent(),dto.getSize(), result.getTotal(), result.getRecords());
    }

    @Override
    public boolean insert(UserInfo userInfo) {
        return dao.insert(userInfo) > 0;
    }

    @Override
    public boolean update(UserInfoUpdateDTO dto) {
        UserInfo userInfo = MapperUtils.map(UserInfo.class, dto);
        userInfo.setId(dto.getUserId());
        UserInfoAttach attach = MapperUtils.map(UserInfoAttach.class, dto);
        dao.updateById(userInfo);
        userInfoAttachDao.update(attach,new LambdaQueryWrapper<UserInfoAttach>().eq(UserInfoAttach::getUserId, userInfo.getId()));
        return true;
    }

    @Override
    public UserInfoGetById getById(Long id) {
        UserInfo userInfo = dao.selectById(id);
        UserInfoGetById map = MapperUtils.map(UserInfoGetById.class, userInfo);

        LambdaQueryWrapper<UserInfoAttach> eq = new QueryWrapper<UserInfoAttach>().lambda().eq(UserInfoAttach::getUserId, userInfo.getId());
        List<UserInfoAttach> userInfoAttaches = userInfoAttachDao.selectList(eq);
        if (userInfoAttaches == null || userInfoAttaches.size() == 0){
            return map;
        }

        UserInfoAttach userInfoAttach = userInfoAttaches.get(0);

        BeanUtils.copyProperties(userInfoAttach,map);

        return map;
    }

    @Override
    public boolean delete(List<Long> userId) {
        return dao.deleteBatchIds(userId) > 0;
    }

    @Transactional(readOnly = false, rollbackFor = AdminBusinessException.class)
    @Override
    public boolean userAuthorize(Long userId, List<Long> roleIds) {
        LambdaQueryWrapper<UserRole> eq = new QueryWrapper<UserRole>().lambda().eq(UserRole::getUserId, userId);
        userRoleService.remove(eq);
        List<UserRole> collect = roleIds.stream().map(o -> {
            UserRole userRole = new UserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(o);
            return userRole;
        }).collect(Collectors.toList());
        return userRoleService.saveBatch(collect);
    }

    @Override
    public List<String> getPermission(Long userId) {
        return dao.selectJoinList(String.class,
                new MPJLambdaWrapper<UserInfo>()
                        .select(Menu::getMenuValue)
                        .leftJoin(UserRole.class, UserRole::getUserId, UserInfo::getId)
                        .leftJoin(RoleMenu.class, RoleMenu::getRoleId, UserRole::getRoleId)
                        .leftJoin(Menu.class, Menu::getMenuId, RoleMenu::getMenuId)
                        .eq(UserInfo::getId, userId)
                        .eq(Menu::getType,3)
                        .eq(Menu::getMenuStatus,1));
    }


    @Override
    public List<MenuTree> getMenuTree(UserMenusDTO dto) {
        AssertUtils.checkTrue(null == dto || null == dto.getUserId(), ErrorEnum.USER20000008);
        //查询该用户有哪些角色
        LambdaQueryWrapper<UserRole> userRoleQuery = new QueryWrapper<UserRole>().lambda().eq(UserRole::getUserId, dto.getUserId());
        List<UserRole> list = userRoleService.list(userRoleQuery);
        if (null == list || list.size() == 0) {
            throw new AdminBusinessException(ErrorEnum.ADMIN10000001);
        }
        List<Long> roleIds = list.stream().map(UserRole::getRoleId).collect(Collectors.toList());
        return  roleService.getRolePerssions(roleIds);
    }
}
